package com.btcode.redis;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;

@SuppressWarnings({"ALL", "UnusedDeclaration"})
public class RedisDbExecute {
    private static JedisPool pool = null;
    private static int dbIndex = 0;
    private static String host = "127.0.0.1";
    static DateTimeFormatter DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    private static void initPool() {
        JedisPoolConfig config = new JedisPoolConfig();
        // 控制一个pool可分配多少个jedis实例，通过pool.getResource()来获取；
        // 如果赋值为-1，则表示不限制；如果pool已经分配了maxActive个jedis实例，则此时pool的状态为exhausted(耗尽)。
        config.setMaxIdle(500);
        // 控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。
        config.setMaxIdle(5);
        // 表示当borrow(引入)一个jedis实例时，最大的等待时间，如果超过等待时间，则直接抛出JedisConnectionException；
        config.setMaxWaitMillis(1000 * 100);
        // 在borrow一个jedis实例时，是否提前进行validate操作；如果为true，则得到的jedis实例均是可用的；
        config.setTestOnBorrow(true);
        // pool = new JedisPool(config, "192.168.0.121", 6379, 100000);
        pool = new JedisPool(config, host, 6379, 100000);
    }

    public static void setRedisDBConfig(String dbHoust) {
        host = dbHoust;
    }

    public static void setDb(int index) {
        dbIndex = index;
    }

    public static Jedis getDb() {
        if (pool == null) {
            initPool();
        }
        Jedis jedis = pool.getResource();
        jedis.select(dbIndex);
        return jedis;
    }

    public static void resetDB() {
        try (Jedis jedis = getDb()) {
            Set<String> MNkeys = jedis.keys("stationInfo:*:deviceInfo:channelId");
            Set<String> Channelkeys = jedis.keys("channelInfo*");
            MNkeys.forEach(RedisDbExecute::delValue);
            Channelkeys.forEach(RedisDbExecute::delValue);
        }
        catch (Exception e) {
//            return null;
        }
    }

    public static void setMapString(String key, String fieldName, String value) {
        try (Jedis jedis = getDb()) {
            jedis.hset(key, fieldName, value);
        }
        catch (Exception e) {
//            return null;
        }
    }

    public static void setMapDate(String key, String fieldName, Date value) {
        try (Jedis jedis = getDb()) {
            jedis.hset(key, fieldName, DTF.format(LocalDateTime.ofInstant(value.toInstant(), ZoneId.systemDefault())));
        }
        catch (Exception e) {
//            return null;
        }
    }

    public static void setString(String key, String value) {
        try (Jedis jedis = getDb()) {
            jedis.set(key, value);
        }
        catch (Exception e) {
//            return null;
        }
    }

    public static void setString(String key, String value, int second) {
        try (Jedis jedis = getDb()) {
            jedis.set(key, value);
            jedis.expire(key, second);
        }
        catch (Exception e) {
//            return null;
        }
    }

    private static void delValue(String key) {
        try (Jedis jedis = getDb()) {
            jedis.del(key);
        }
        catch (Exception e) {
//            return null;
        }
    }

    public static String getMapString(String key, String fieldName) {
        try (Jedis jedis = getDb()) {
            return jedis.hget(key, fieldName);
        }
        catch (Exception e) {
            return null;
        }
    }

    public static String getString(String key) {
        try (Jedis jedis = getDb()) {
            return jedis.get(key);
        }
        catch (Exception e) {
            return null;
        }
    }

    public static Integer getMapInt(String key, String fieldName) {
        try (Jedis jedis = getDb()) {
            return toInt(jedis.hget(key, fieldName));
        }
        catch (Exception e) {
            return null;
        }
    }

    public static Integer getInt(String key) {
        try (Jedis jedis = getDb()) {
            return toInt(jedis.get(key));
        }
        catch (Exception e) {
            return null;
        }
    }

    public static Double getMapDouble(String key, String fieldName) {
        try (Jedis jedis = getDb()) {
            return toDouble(jedis.hget(key, fieldName));
        }
        catch (Exception e) {
            return null;
        }
    }

    public static Double getDouble(String key) {
        try (Jedis jedis = getDb()) {
            return toDouble(jedis.get(key));
        }
        catch (Exception e) {
            return null;
        }
    }

    public static Date getMapDate(String key, String fieldName, String pattern) {
        try (Jedis jedis = getDb()) {
            return toDate(jedis.hget(key, fieldName), pattern);
        }
        catch (Exception e) {
            return null;
        }
    }

    public static Date getDate(String key, String pattern) {
        try (Jedis jedis = getDb()) {
            return toDate(jedis.get(key), pattern);
        }
        catch (Exception e) {
            return null;
        }
    }

    private static Integer toInt(String value) {
        if (value == null) {
            return null;
        }
        Integer intValue = null;
        try {
            intValue = Integer.parseInt(value);
        }
        catch (Exception e) {
            return null;
        }
        return intValue;
    }

    private static Double toDouble(String value) {
        if (value == null) {
            return null;
        }
        Double doubleValue = null;
        try {
            doubleValue = Double.parseDouble(value);
        }
        catch (Exception e) {
            return null;
        }
        return doubleValue;
    }

    private static Date toDate(String value, String pattern) {
        if (value == null) {
            return null;
        }
        DateTimeFormatter sf = null;
        if (pattern == null) {
            sf = DTF;
        }
        else {
            sf = DateTimeFormatter.ofPattern(pattern);
        }
        Date dateValue = null;
        try {
            dateValue = Date.from(LocalDateTime.parse(value, sf).atZone(ZoneId.systemDefault()).toInstant());
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return dateValue;
    }

    /**
     * 模糊匹配key
     * gislin
     * 2016年3月17日
     *
     * @param parentKey
     * @return
     */
    public static Set<String> queryKeys(String parentKey) {
        try (Jedis jedis = getDb()) {
            Set<String> treeKeys = new TreeSet<>();
            Set<String> keys = jedis.keys(parentKey + "*");
            treeKeys.addAll(keys.stream().collect(Collectors.toList()));
            return treeKeys;
        }
        catch (Exception e) {
            return null;
        }
    }

    /**
     * 模糊删除key
     * gislin
     * 2016年3月24日
     *
     * @param keyPattern
     */
    public static void deleteKeys(String keyPattern) {
        Set<String> keys = queryKeys(keyPattern);
        if (keys != null) {
            keys.forEach(RedisDbExecute::delValue);
        }
    }
}
